//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package appstore_dao

import (
	"context"
	"fmt"

	"atomgit.com/openlinksaas-org/api-server/dao/db_ns"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
)

type AgreeDbItem struct {
	AgreeId string `bson:"_id"`
	AppId   string `bson:"appId"`
	UserId  string `bson:"userId"`
}

type _AgreeDao struct {
	mc *mongo.Collection
}

func newAgreeDao(db *mongo.Database) (*_AgreeDao, error) {
	mc := db.Collection(db_ns.DB_NS_APP_STORE + "agree")
	_, err := mc.Indexes().CreateOne(context.Background(), mongo.IndexModel{
		Keys: bson.D{{"appId", 1}},
	})
	if err != nil {
		return nil, err
	}
	return &_AgreeDao{mc: mc}, nil
}

func (db *_AgreeDao) Insert(ctx context.Context, dbItem *AgreeDbItem) error {
	dbItem.AgreeId = db.genAgreeId(dbItem.AppId, dbItem.UserId)
	_, err := db.mc.InsertOne(ctx, dbItem)
	return err
}

func (db *_AgreeDao) genAgreeId(appId, userId string) string {
	return fmt.Sprintf("%s:%s", appId, userId)
}

func (db *_AgreeDao) Exist(ctx context.Context, appId, userId string) (bool, error) {
	agreeId := db.genAgreeId(appId, userId)
	count, err := db.mc.CountDocuments(ctx, bson.M{"_id": agreeId, "appId": appId})
	return count > 0, err
}

func (db *_AgreeDao) Remove(ctx context.Context, appId, userId string) (bool, error) {
	agreeId := db.genAgreeId(appId, userId)
	res, err := db.mc.DeleteOne(ctx, bson.M{"_id": agreeId, "appId": appId})
	if err != nil {
		return false, err
	}
	return res.DeletedCount > 0, nil
}

func (db *_AgreeDao) RemoveByApp(ctx context.Context, appId string) error {
	_, err := db.mc.DeleteMany(ctx, bson.M{"appId": appId})
	return err
}

func (db *_AgreeDao) DistinctAppId(ctx context.Context, appIdList []string, userId string) ([]string, error) {
	agreeIdList := []string{}
	for _, appId := range appIdList {
		agreeIdList = append(agreeIdList, db.genAgreeId(appId, userId))
	}
	tmpIdList, err := db.mc.Distinct(ctx, "appId", bson.M{"_id": bson.M{"$in": agreeIdList}, "userId": userId})
	if err != nil {
		return nil, err
	}
	retList := []string{}
	for _, tmpId := range tmpIdList {
		retList = append(retList, tmpId.(string))
	}
	return retList, nil
}
